package com.bear.newsset.widget.item;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;

import com.bear.newsset.R;

/**
 * 新闻Item组件 - 基类
 * 所有新闻ItemView都要继承
 *
 * 必须通过onTouch调用该方法才能实现点击操作，因为自身实现容易和调用者发生冲突。
 * @see #onLongClickEvent(MotionEvent)
 */
public class BaseNewsItemView extends FrameLayout implements View.OnClickListener {
    /**
     * 更多类型
     */
    public enum CLICK_TYPE {
        GIVE_LIKE,      //喜欢按钮
        COLLECT,        //收藏按钮
        SHARE           //分享按钮
    }

    /**
     * 更多点击事件监听器
     */
    public interface OnClickMoreInsideBtnListener {
        void onClick(View v, CLICK_TYPE type, boolean isSelect);
    }

    public interface OnLongClickListener {
        void onLongClick(BaseNewsItemView v);
    }

    private final int KEY_TOUCH = -1000000;
    private final int KEY_EFFECT = -1000001;

    private Context mContext;
    private BaseNewsItemView mThis;
    private View vMore;
    private TextView tvGiveLikeBtn, tvCollectBtn, tvShareBtn;

    private GestureDetector mGesture;
    private boolean mEnableLongClickMore;
    private OnClickMoreInsideBtnListener mOnClickMoreInsideBtnListener;
    private OnLongClickListener mOnLongClickListener;

    private AlertDialog mDialog;

    public BaseNewsItemView(@NonNull Context context) {
        super(context);
        init( context );
    }

    public BaseNewsItemView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init( context );
    }

    public BaseNewsItemView(@NonNull Context context, @Nullable AttributeSet attrs,
                            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init( context );
    }

    /**
     * 初始化
     * @param mContext  上下文
     */
    public void init(Context mContext) {
        this.mContext = mContext;
        mThis = this;
        setLayoutParams(
                new LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
                )
        );
        initView();
        initData();
        initListener();
    }

    /**
     * 初始化视图
     */
    @SuppressLint("InflateParams")
    private void initView() {
        LayoutInflater inflater = LayoutInflater.from( mContext );

        vMore = inflater.inflate(R.layout.block_news_more, null);

        tvGiveLikeBtn = vMore.findViewById(R.id.item_news_more_tv_give_like_btn);
        tvCollectBtn = vMore.findViewById(R.id.item_news_more_tv_collect_btn);
        tvShareBtn = vMore.findViewById(R.id.item_news_more_tv_share_btn);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        mEnableLongClickMore = true;
        vMore.setFocusable( true );
        vMore.setClickable( true );
        //取消分享按钮按下的效果
        setEnablePressEffect(false, CLICK_TYPE.SHARE);
    }

    /**
     * 初始化监听器
     */
    private void initListener() {
        //点赞按钮 点击事件监听器
        tvGiveLikeBtn.setOnClickListener( this );
        //收藏按钮 点击事件监听器
        tvCollectBtn.setOnClickListener( this );
        //转发按钮 点击事件监听器
        tvShareBtn.setOnClickListener( this );
        //触摸监听器
        mGesture = new GestureDetector(mContext, new SimpleOnGestureListener() {
            /**
             * Item长按时监听
             * @param e     事件
             */
            @Override
            public void onLongPress(MotionEvent e) {
                super.onLongPress(e);
                if( mOnLongClickListener != null ) mOnLongClickListener.onLongClick( mThis );
                //显示更多
                showMoreView();
            }
        });
    }

    /**
     * 初始化更多中的按钮状态
     * @param isSelectLike      是否选中喜欢
     * @param isSelectCollect   是否选中收藏
     * @param isSelectShare     是否选中分享
     */
    public void initMoreInsideBtnStatus(boolean isSelectLike,
                                        boolean isSelectCollect,
                                        boolean isSelectShare) {
        //初始化Tag
        initViewTag(tvGiveLikeBtn, tvCollectBtn, tvShareBtn);
        changeViewStatus(tvGiveLikeBtn, isSelectLike);
        changeViewStatus(tvCollectBtn, isSelectCollect);
        changeViewStatus(tvShareBtn, isSelectShare);
    }

    private void initViewTag(View... views) {
        for( View v : views ) {
            //默认不选中
            if( v.getTag( KEY_TOUCH ) == null ) v.setTag(KEY_TOUCH, 0);
            //默认有按下效果
            if( v.getTag( KEY_EFFECT ) == null ) v.setTag(KEY_EFFECT, 1);
        }
    }


    /**
     * 通过布局资源创建View
     * @param res       布局资源
     * @return          {@link View}
     */
    public View createView(@LayoutRes int res) {
        return LayoutInflater.from( mContext ).inflate(res, null);
    }

    /**
     * 该View不做任何点击处理，所以长按处理需要交给调用者去调用，即onTouch监听
     * @param ev    {@link MotionEvent}
     */
    public void onLongClickEvent(MotionEvent ev) {
        mGesture.onTouchEvent( ev );
    }

    /**
     * 设置是否显示"更多控件"
     * @param isShow    是否显示
     */
    private void setShowMoreView(boolean isShow) {
        if( !mEnableLongClickMore ) return;
        Window w;
        WindowManager.LayoutParams lp;
        if( mDialog == null ) {
            AlertDialog.Builder b = new AlertDialog.Builder( mContext, R.style.DialogBottom );
            b.setView( vMore );
            mDialog = b.create();
        }

        if( isShow ) {
            mDialog.show();
        }else {
            mDialog.dismiss();
        }

        if( (w = mDialog.getWindow()) != null ) {
            lp = w.getAttributes();
            //宽度占满屏幕
            lp.width = WindowManager.LayoutParams.MATCH_PARENT;
            w.setAttributes( lp );
            //显示在底部
            w.setGravity( Gravity.BOTTOM );
            //取消边距
            w.getDecorView().setPadding(0, 0, 0, 0);
        }
    }

    public void showMoreView() { setShowMoreView( true ); }

    public void hideMoreView() { setShowMoreView( false ); }

    /**
     * 是否启用按下效果
     * @param enable    是否启用
     * @param type      按钮类型
     */
    public void setEnablePressEffect(boolean enable, CLICK_TYPE type) {
        int val = enable ? 1 : 0;
        switch ( type ) {
            case GIVE_LIKE:
                tvGiveLikeBtn.setTag(KEY_EFFECT, val);
                break;
            case COLLECT:
                tvCollectBtn.setTag(KEY_EFFECT, val);
                break;
            case SHARE:
                tvShareBtn.setTag(KEY_EFFECT, val);
                break;
        }
    }
    public void setEnablePressEffect(boolean enable, CLICK_TYPE... types) {
        for( CLICK_TYPE type : types ) {
            setEnablePressEffect(enable, type);
        }
    }

    /**
     * 设置启用长按弹出更多
     * @param enable        是否启用
     */
    public void setEnableLongClickMore(boolean enable) {
        mEnableLongClickMore = enable;
    }

    /**
     * 是否已启用长按弹出更多
     * @return      结果
     */
    public boolean isEnableLongClickMore() {
        return mEnableLongClickMore;
    }

    /**
     * 隐藏不需要的更多按钮
     * @param types     隐藏类型
     */
    public void hideMoreBtn(@NonNull CLICK_TYPE... types) {
        for (CLICK_TYPE type : types) {
            int id = 0;
            switch ( type ) {
                case GIVE_LIKE:
                    id = R.id.item_news_more_give_like_layout;
                    break;
                case COLLECT:
                    id = R.id.item_news_more_collect_layout;
                    break;
                case SHARE:
                    id = R.id.item_news_more_share_layout;
                    break;
            }
            vMore.findViewById( id ).setVisibility( View.GONE );
        }
    }

    /**
     * More 上的按钮点击事件监听器
     * @param listener      回调
     */
    public void setOnClickMoreInsideBtnListener(OnClickMoreInsideBtnListener listener) {
        mOnClickMoreInsideBtnListener = listener;
    }

    /**
     * 长按时回调长按监听器
     * @param listener      回调
     */
    public void setOnLongClickListener(OnLongClickListener listener) {
        mOnLongClickListener = listener;
    }

    /**
     * More 上的按钮回调接口
     * @param v     回调的按钮View
     */
    @Override
    public void onClick(View v) {
        CLICK_TYPE type = null;
        //取反改变View的状态
        boolean isTouch = changeViewStatus( v );
        //当前点击的类型
        switch ( v.getId() ) {
            case R.id.item_news_more_tv_give_like_btn:
                type = CLICK_TYPE.GIVE_LIKE;
                break;
            case R.id.item_news_more_tv_collect_btn:
                type = CLICK_TYPE.COLLECT;
                break;
            case R.id.item_news_more_tv_share_btn:
                type = CLICK_TYPE.SHARE;
                //隐藏更多
                hideMoreView();
                break;
        }
        //回调点击的类型
        if( type != null && mOnClickMoreInsideBtnListener != null ) {
            mOnClickMoreInsideBtnListener.onClick(v, type, isTouch);
        }
    }

    /**
     * 改变View的状态    true：实心，false：空心
     * @param v        View
     */
    private void changeViewStatus(@NonNull View v, boolean isTouch, boolean isEffect) {
        TextView tv = (TextView) v;
        int whiteColor = getResources().getColor( R.color.colorWhite );
        int mainColor = getResources().getColor( R.color.colorChild );
        //保存是否选中状态
        v.setTag(KEY_TOUCH, isTouch ? 1 : 0);
        //不需要按下按效果
        if( !isEffect ) return;
        //设置文本颜色
        tv.setTextColor( isTouch ? whiteColor : mainColor );
        //设置背景
        tv.setBackgroundResource(isTouch ?
                R.drawable.shape_main_color_solid_oval : R.drawable.shape_main_color_hollow_oval
        );
    }

    /**
     * 改变View的状态     tag中的effect=1时：按下有效果，其他：按下没效果
     * @param v         View
     * @param isTouch   是否选中
     */
    private void changeViewStatus(@NonNull View v, boolean isTouch) {
        boolean isEffect = (int) v.getTag( KEY_EFFECT ) == 1;
        changeViewStatus(v, isTouch, isEffect);
    }

    /**
     * 改变View的状态    tag中的touch=1时：false，其他：true
     *                 tag中的effect=1时：按下有效果，其他：按下没效果
     *
     * 改变状态之前需要在点击之前初始化按钮的状态，否则会抛异常
     * @see #initMoreInsideBtnStatus(boolean, boolean, boolean)
     * @param v        View
     * @return         选中结果
     */
    private boolean changeViewStatus(@NonNull View v) {
        //取反改变状态
        boolean isTouch = !( (int) v.getTag( KEY_TOUCH ) == 1 );
        boolean isEffect = (int) v.getTag( KEY_EFFECT ) == 1;
        changeViewStatus( v, isTouch, isEffect );
        return isTouch;
    }
}
